package com.yscp.ysdemo.config;


import com.yscp.ysdemo.filter.JwtAuthenticationTokenFilter;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
import org.springframework.security.authentication.AuthenticationManager;
import org.springframework.security.config.annotation.web.builders.HttpSecurity;
import org.springframework.security.config.annotation.web.configuration.WebSecurityConfigurerAdapter;
import org.springframework.security.config.http.SessionCreationPolicy;
import org.springframework.security.crypto.bcrypt.BCryptPasswordEncoder;
import org.springframework.security.crypto.password.PasswordEncoder;
import org.springframework.security.web.authentication.UsernamePasswordAuthenticationFilter;

import javax.annotation.Resource;

@Configuration
public class SecurityConfig extends WebSecurityConfigurerAdapter {

    @Resource
    private JwtAuthenticationTokenFilter jwtAuthenticationTokenFilter;


    /**
     * 需要放入该bean才能在其他地方注入 AuthenticationManager
     * @return
     * @throws Exception
     */
    @Bean
    @Override
    public AuthenticationManager authenticationManagerBean() throws Exception {
        return super.authenticationManagerBean();
    }

    //直接定死使用此加密算法
    @Bean
    public PasswordEncoder passwordEncoder(){
        return new BCryptPasswordEncoder();
    }

    @Override
    protected void configure(HttpSecurity http) throws Exception {

//        如果追源码会发现如果没有super.configure(http),那么 UsernamePasswordAuthenticationFilter也不会被
//         创建并加入到过滤器链，所以这里addFilterBefore(jwtAuthenticationTokenFilter, UsernamePasswordAuthenticationFilter.class);
//        后，其实最终相当于用自定义的过滤器取代了UsernamePasswordAuthenticationFilter
        http.csrf().disable()
                //session设置成不需要通过session获取到securityContext，因为目前是采取redis存储用户信息，不经过session
                .sessionManagement().sessionCreationPolicy(SessionCreationPolicy.STATELESS)
                .and()
                .authorizeRequests()
                .mvcMatchers("/user/userLogin",
                            "/user/registeredCheck",
                            "/user/doPost/getTags",
                            "/user/getUserMsg",
                            "/user/doPost/searchTag",
                            "/user/registered",
                            "/user/searchMyFans",
                            "/user/searchFocusUser",
                            "/user/getUserMsg").anonymous()
                //anonymous表示未认证才能访问，认证过了就不能访问了,而permitAll()表示无论是否认证都能访问，
                //本项目用anonymous表示没登录才能访问loginTest登录接口，登录了就不能登录了
                .anyRequest().authenticated()
                .and().formLogin()
                //之后在进行认证的时候，先经过自定义的jwtAuthenticationTokenFilter检查token的合法性
                .and().addFilterBefore(jwtAuthenticationTokenFilter, UsernamePasswordAuthenticationFilter.class);


    }
}
